﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;
using HYRElectric.WirePlace;

namespace HYRElectric.Equipment
{
	public class DragLineLayout : EquipmentLayout
	{
		public DragLineLayout(UIDocument uiDoc, Document document, DbFamilyObject familyObject, FamilySymbol selectedFamilySymbol, List<BuiltInCategory> lstFilter) : base(uiDoc, document, familyObject, selectedFamilySymbol, lstFilter)
		{
		}

		public override bool Layout()
		{
			if (!base.Layout())
			{
				return false;
			}
			this.form = new DragLineLayoutForm(this.doc);
			this.form.Show(WindowHelper.HWndRevit);
			WindowHelper.SendMessageToWndRevit();
			for (;;)
			{
				try
				{
					this.startPoint = this.docUI.Selection.PickPoint("请选取起点");
					LayoutEquipmentJig layoutEquipmentJig = new LayoutEquipmentJig(this.docUI, this.form);
					this.endPoint = layoutEquipmentJig.PickEndPoint(this.startPoint, LayoutEquipmentJig.ELayoutType.eLine, "请选取终点");
					layoutEquipmentJig.Dispose();
					if (this.endPoint == null)
					{
						break;
					}
					if ((this.endPoint - this.startPoint).IsZeroLength())
					{
						TaskDialog.Show("盈建科提示", "选取的两点为同一点，请选取两个不同点。");
						continue;
					}
				}
				catch (Exception)
				{
					break;
				}
				List<XYZ> insertPoints = this.GetInsertPoints();
				if (insertPoints != null && insertPoints.Count > 0)
				{
					double angle = Convert.ToDouble(this.form.Angle);
					if (this.form.IsAutoAngle)
					{
						angle = this.GetLineAngle();
					}
					TransactionGroup transactionGroup = new TransactionGroup(this.doc, "TransactionGroup");
					try
					{
						transactionGroup.Start();
						FamilyInstance familyInstance = null;
						foreach (XYZ xyz in insertPoints)
						{
							Transaction transaction = null;
							try
							{
								transaction = new Transaction(this.doc, "DragLineLayout");
								transaction.Start();
								FamilyInstance familyInstance2 = YJKRevitTools.LayFamilySymbol(this.doc, xyz, this.familySymbol, this.doc.ActiveView.GenLevel, angle);
								if (familyInstance2 == null)
								{
									throw new Exception("布置设备出错。");
								}
								base.SetParametersValue(familyInstance2, this.dbFamilyObject.Size);
								transaction.Commit();
								if (this.form.IsLink && familyInstance != null)
								{
                                    NewConnectWire.CreateWire(this.doc, familyInstance, familyInstance2, (Autodesk.Revit.DB.Electrical.WiringType)this.form.WireStyle, null);
								}
								familyInstance = familyInstance2;
							}
							catch (Exception)
							{
								if (transaction != null && transaction.GetStatus() != TransactionStatus.Committed)
								{
									transaction.RollBack();
								}
								break;
							}
						}
						transactionGroup.Assimilate();
						continue;
					}
					catch (Exception)
					{
						transactionGroup.RollBack();
						continue;
					}
					break;
				}
			}
			this.form.Close();
			return true;
		}

		private List<XYZ> GetInsertPoints()
		{
			if (this.form == null)
			{
				return null;
			}
			List<XYZ> list = new List<XYZ>();
			if (this.form.AlignWay == 0)
			{
				double num = this.startPoint.DistanceTo(this.endPoint);
				double num2 = UnitConvert.LengthToStd(Convert.ToDouble(this.form.Space) / 1000.0);
				for (double num3 = UnitConvert.LengthToStd(Convert.ToDouble(this.form.SpaceToStart) / 1000.0); num3 < num; num3 += num2)
				{
					XYZ item = this.startPoint + num3 * (this.endPoint - this.startPoint).Normalize();
					list.Add(item);
				}
			}
			else
			{
				double num4 = this.startPoint.DistanceTo(this.endPoint) * 0.5;
				double num5 = UnitConvert.LengthToStd(Convert.ToDouble(this.form.Space) / 1000.0);
				double num6 = num5;
				XYZ xyz = this.startPoint + num4 * (this.endPoint - this.startPoint).Normalize();
				list.Add(xyz);
				while (num6 < num4)
				{
					XYZ item2 = xyz - num6 * (this.endPoint - this.startPoint).Normalize();
					XYZ item3 = xyz + num6 * (this.endPoint - this.startPoint).Normalize();
					list.Add(item2);
					list.Add(item3);
					num6 += num5;
				}
				list.Sort(new Comparison<XYZ>(this.PointCompare));
			}
			return list;
		}

		private int PointCompare(XYZ pt1, XYZ pt2)
		{
			if (Math.Abs(this.startPoint.DistanceTo(pt1) - this.startPoint.DistanceTo(pt2)) < 0.01)
			{
				return 0;
			}
			if (this.startPoint.DistanceTo(pt1) < this.startPoint.DistanceTo(pt2))
			{
				return -1;
			}
			return 1;
		}

		private double GetLineAngle()
		{
			return AssistFunc.RadianToAngle(XYZ.BasisX.AngleOnPlaneTo(this.endPoint - this.startPoint, XYZ.BasisZ));
		}

		private XYZ startPoint;

		private XYZ endPoint;

		private DragLineLayoutForm form;
	}
}
